/*
*	(*^。^*) TFrameWork License (*^。^*)
*/

/*
 *  Title :  
 *          
 *  Description :  
 *          
 *          
 *  Date : 
 *
 *  Author : DengPing
 *
 *  Modify : 
 */
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace TFrameWork.Module.ActionEditor
{
    internal partial class ActionEditor
    {
        private IMGUIContainer _timerShaft;
        private IMGUIContainer _selectLine;

        //用于调整缩放
        private VisualElement _contentContainer;
        private VisualElement _contentViewPort;

        private int _currentSelectFrameIndex = -1;

        public int CurrentSelectFrameIndex
        {
            get => _currentSelectFrameIndex;
            private set
            {
                int old = _currentSelectFrameIndex;
                // 如果超出范围，更新最大帧
                if (value > CurrentFrameCount) CurrentFrameCount = value;
                _currentSelectFrameIndex = Mathf.Clamp(value, 0, CurrentFrameCount);
                CurrentFrameField.value = _currentSelectFrameIndex;

                if (old != _currentSelectFrameIndex)
                {
                    UpdateTimerShaftView();
                    TickPreView();
                }

                if (value == CurrentFrameCount && IsRecordEvent)
                {
                    if (IsRecordEvent)
                    {
                        IsRecordEvent = false;
                    }
                }
            }
        }

        private int _currentFrameCount;

        public int CurrentFrameCount
        {
            get => _currentFrameCount;
            set
            {
                _currentFrameCount = value;
                FrameCountField.value = _currentFrameCount;
                // 同步给SkillConfig
                if (_actionData != null)
                {
                    _actionData.FrameCount = _currentFrameCount;
                }

                // Content区域的尺寸变化
                UpdateContentSize();
            }
        }

        /// <summary>
        /// 当前内容区域的偏移坐标 拖动滚动条的偏移量
        /// </summary>
        private float _contentOffsetPos => Mathf.Abs(_contentContainer.transform.position.x);

        private float _currentSlectFramePos => _currentSelectFrameIndex * _actionEditorConfig.frameUnitWidth;

        private bool _timerShaftIsMouseEnter = false;


        /// <summary>
        /// 初始化时间轴
        /// </summary>
        private void InitTimerShaft()
        {
            ScrollView MainContentView = _root.Q<ScrollView>("MainContentView");
            _contentContainer = MainContentView.Q<VisualElement>("unity-content-container");
            _contentViewPort = MainContentView.Q<VisualElement>("unity-content-viewport");

            _timerShaft = _root.Q<IMGUIContainer>("TimerShaft");
            _timerShaft.onGUIHandler = DrawTimerShaft;

            _selectLine = _root.Q<IMGUIContainer>("SelectLine");
            _selectLine.onGUIHandler = DrawSelectLine;

            //监听鼠标的操作
            _timerShaft.RegisterCallback<WheelEvent>(TimerShaftWheel);
            //监听鼠标移动
            _timerShaft.RegisterCallback<MouseDownEvent>(TimerShaftMouseDown);
            _timerShaft.RegisterCallback<MouseMoveEvent>(TimerShaftMouseMove);
            _timerShaft.RegisterCallback<MouseUpEvent>(TimerShaftMouseUp);
            _timerShaft.RegisterCallback<MouseOutEvent>(TimerShaftMouseOut);
        }

        /// <summary>
        /// IMGUI的绘制函数，绘制时间轴
        /// </summary>
        private void DrawTimerShaft()
        {
            Handles.BeginGUI();
            {
                Handles.color = Color.white;
                Rect rect = _timerShaft.contentRect;

                // 起始索引  (内容区域的偏移 / 当前的帧宽）
                int index = Mathf.CeilToInt(_contentOffsetPos / _actionEditorConfig.frameUnitWidth);

                // 计算绘制起点的偏移
                float startOffset = 0;
                if (index > 0)
                {
                    //起始偏移帧 = 当前的帧宽 - 偏移量和帧宽的余数。
                    startOffset = _actionEditorConfig.frameUnitWidth -
                                  (_contentOffsetPos % _actionEditorConfig.frameUnitWidth);
                }

                //计算绘制数字文本的间隔
                int tickStep = ActionEditor.Instance.actionEditorConfig.maxFrameWidthLV + 1 -
                               (_actionEditorConfig.frameUnitWidth / ActionEditor.Instance.actionEditorConfig.standFrameUnitWidth);
                tickStep = tickStep / 2; // 可能 1 / 2 = 0的情况
                if (tickStep == 0) tickStep = 1; // 避免为0

                for (float i = startOffset; i < rect.width; i += _actionEditorConfig.frameUnitWidth)
                {
                    // 绘制长线、文本
                    if (index % tickStep == 0)
                    {
                        Handles.DrawLine(new Vector3(i, rect.height - 10), new Vector3(i, rect.height));
                        string indexStr = index.ToString();
                        GUI.Label(new Rect(i - indexStr.Length * 4.5f, 0, 35, 20), indexStr);
                    }
                    else Handles.DrawLine(new Vector3(i, rect.height - 5), new Vector3(i, rect.height));

                    index += 1;
                }
            }
            Handles.EndGUI();
        }

        /// <summary>
        /// 滚轮的缩放操作
        /// </summary>
        /// <param name="evt"></param>
        private void TimerShaftWheel(WheelEvent evt)
        {
            int delta = (int)evt.delta.y;
            //限制帧宽
            _actionEditorConfig.frameUnitWidth = Mathf.Clamp(_actionEditorConfig.frameUnitWidth - delta,
                ActionEditor.Instance.actionEditorConfig.standFrameUnitWidth,
                ActionEditor.Instance.actionEditorConfig.maxFrameWidthLV * ActionEditor.Instance.actionEditorConfig.standFrameUnitWidth);

            UpdateTimerShaftView();
            UpdateContentSize();
            
            ResetLoadTrack();
        }

        private void TimerShaftMouseDown(MouseDownEvent evt)
        {
            // 让选中线得位置卡在帧的位置上
            if (_timerShaftIsMouseEnter)
            {
                MouseMoveEvent -= TimerShaftMouseMove;
                MouseUpEvent -= TimerShaftMouseUp;
                MouseOutEvent -= TimerShaftMouseOut;
            }
            
            _timerShaftIsMouseEnter = true;
            IsPlaying = false;
            int newValue = GetFrameIndexByMousePos(evt.localMousePosition.x);
            if (newValue != CurrentSelectFrameIndex)
            {
                if (IsRecordEvent) IsRecordEvent = false;
                CurrentSelectFrameIndex = newValue;
            }
            MouseMoveEvent += TimerShaftMouseMove;
            MouseUpEvent += TimerShaftMouseUp;
            MouseOutEvent += TimerShaftMouseOut;
        }

        private void TimerShaftMouseMove(MouseMoveEvent evt)
        {
            if (_timerShaftIsMouseEnter)
            {
                int newValue = GetFrameIndexByMousePos(evt.localMousePosition.x);
                if (newValue != CurrentSelectFrameIndex)
                {
                    CurrentSelectFrameIndex = newValue;
                }
            }
        }

        private void TimerShaftMouseUp(MouseUpEvent evt)
        {
            _timerShaftIsMouseEnter = false;
            MouseMoveEvent -= TimerShaftMouseMove;
            MouseUpEvent -= TimerShaftMouseUp;
            MouseOutEvent -= TimerShaftMouseOut;
        }

        private void TimerShaftMouseOut(MouseOutEvent evt)
        {
            var localPos = _timerShaft.WorldToLocal(evt.mousePosition);
            if (!_timerShaft.ContainsPoint(localPos))
            {
                var pos = TrackBackGround.WorldToLocal(evt.mousePosition);
                if (!TrackBackGround.ContainsPoint(pos))
                {
                    _timerShaftIsMouseEnter = false;
                    MouseMoveEvent -= TimerShaftMouseMove;
                    MouseUpEvent -= TimerShaftMouseUp;
                    MouseOutEvent -= TimerShaftMouseOut;
                }
            }
        }

        /// <summary>
        /// 根据鼠标坐标获取帧索引
        /// </summary>
        private int GetFrameIndexByMousePos(float x)
        {
            return GetFrameIndexByPos(x + _contentOffsetPos);
        }

        /// <summary>
        /// 四舍五入到最近的关键帧
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public int GetFrameIndexByPos(float x)
        {
            return Mathf.RoundToInt(x / _actionEditorConfig.frameUnitWidth);
        }

        /// <summary>
        /// IMGUI的绘制函数 绘制选中线
        /// </summary>
        private void DrawSelectLine()
        {
            // 判断当前选中帧是否在视图范围内
            if (_currentSlectFramePos >= _contentOffsetPos)
            {
                Handles.BeginGUI();
                {
                    Handles.color = Color.white;
                    float x = _currentSlectFramePos - _contentOffsetPos;
                    Handles.DrawLine(new Vector3(x, 0),
                        new Vector3(x, _contentViewPort.contentRect.height + _timerShaft.contentRect.height));
                }
                Handles.EndGUI();
            }
        }


        private void UpdateTimerShaftView()
        {
            _timerShaft.MarkDirtyLayout(); // 标志为需要重新绘制的
            _selectLine.MarkDirtyLayout(); // 标志为需要重新绘制的
        }

    }
}
